home *** CD-ROM | disk | FTP | other *** search
- /* eshot.c */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h> /* sin,cos を使うために */
- #include <sys/iocs.h>
- #include "XSP2lib.H"
-
- #define PCG_MAX 32 /* パターンデータの個数 */
-
- static char pcg_alt[PCG_MAX + 1]; /* PCG配置管理テーブル */
- static char pcg_dat[PCG_MAX * 128]; /* PCGデータファイル読み込みバッファ */
-
- static unsigned short pal_dat[16][15]; /* パレットデータ */
-
-
- #define ESHOT_MAX 200 /* 敵弾最大数 */
- #define ESHOT_SPEED 0.75 /* 敵弾の速度 */
-
-
- /* 敵弾構造体 */
- typedef struct _eshot {
- signed short x; /* 敵弾のX座標 */
- signed short y; /* 〃 Y座標 */
- unsigned char type; /* 〃 種類(=0 なら未使用) */
- signed int lx, ly; /* 32bit X,Y 座標 ( l = longword ) */
- signed int vx, vy; /* 32bit X,Y 速度 ( v = velocity ) */
- struct _eshot *next; /* 次の構造体へのポインタ */
- } ESHOT;
-
- ESHOT *eshot_top; /* 使用中のワークのリスト */
- int eshot_count; /* 敵弾の数 */
-
-
-
- typedef struct {
- signed int x, y;
- } VECTOR;
-
- VECTOR xytable[256]; /* sin,cos テーブル */
-
-
-
- /* ゲーム開始時に呼ばれる */
- void EshotInit (void)
- {
- eshot_count = 0; /* 敵弾数は0 */
- }
-
-
-
- /* 敵弾出現時に呼ばれる */
- /* 引き数 : 種類, X座標, Y座標, 角度 */
- void EshotAlloc (unsigned char type, signed short x, signed short y, unsigned char angle)
- {
- ESHOT *p;
-
- if (eshot_count >= ESHOT_MAX) /* 敵弾数が ESHOT_MAX を越えているか? */
- return; /* これ以上は出さない */
- eshot_count++;
-
- p = malloc (sizeof (ESHOT)); /* ノードを1個確保 */
- if (p == NULL) /* 確保できたか? */
- return; /* 確保できなかった(メモリ不足) */
-
- /* リスト構造で管理 */
- if (eshot_top == NULL) {
- /* 1個も弾が出ていない場合 */
- p->next = NULL; /* 次はない */
- } else {
- p->next = eshot_top; /* 「今までの先頭」を「今確保したノード」の次にする */
- }
- eshot_top = p; /* 今確保したノードを先頭にする */
-
- p->lx = (x - 8) * 65536; /* (8,8) がスプライト座標の中心なので補正 */
- p->ly = (y - 8) * 65536;
- p->vx = xytable[angle].x;
- p->vy = xytable[angle].y;
- p->type = type;
- }
-
-
-
- /* 垂直同期ごとに呼ばれる */
- void EshotMove (void)
- {
- ESHOT *p, *q;
-
- p = eshot_top; /* 現在注目しているワーク */
- q = NULL; /* 1つ前のワーク(ワーク削除時に必要) */
-
- while (p != NULL) {
- p->lx += p->vx; /* vx だけ移動 */
- p->ly += p->vy; /* vy だけ移動 */
-
- p->x = p->lx / 65536; /* lx の整数部を取り出して x に */
- p->y = p->ly / 65536; /* ly の整数部を取り出して y に */
-
- /* 敵弾が画面外に出たか? */
- if ((p->x < 0) || (p->x > 256 + 16) || (p->y < 0) || (p->y > 256 + 16)) {
- /* 画面外に出たので消去 */
- eshot_count--;
-
- if (q == NULL) { /* リストの一番最初を削除 */
- eshot_top = p->next;
- free (p); /* メモリを開放 */
- q = NULL;
- p = eshot_top;
- } else {
- q->next = p->next;
- free (p); /* メモリを開放 */
- p = q->next;
- }
- } else {
- xsp_set (p->x, p->y, p->type, 0x033f);
-
- q = p;
- p = p->next;
- }
- }
- }
-
-
-
- int main (int argc, char *argv[])
- {
- FILE *fp;
- int i, j;
- int game_over = 0;
- unsigned char angle = 0; /* 次に撃つ弾の角度 */
- unsigned char type = 1; /* 次に撃つ弾の種類 */
- int sprites; /* スプライトの枚数 */
-
- if (argc != 1) {
- printf (
- "敵弾テストその5 ESHOT.X\n"
- " programmed by Mitsuky <FreeSoftware>\n"
- "弾のワークをリスト構造で管理するようにした\n"
- "&弾がちゃんと画面の中央から出るようにした\n"
- );
- exit (-1);
- }
- printf ("データテーブルを作成します。\n");
- for (i = 0; i < 256; i++) {
- xytable[i].x = (signed int) (cos (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
- xytable[i].y = (signed int) (sin (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
- }
-
-
- _iocs_crtmod (10); /* 256x256ドット グラフィック画面 256色 2画面 */
- _iocs_g_clr_on (); /* グラフィック画面の初期化 */
- _iocs_sp_init (); /* スプライトの初期化 */
- _iocs_sp_on ();
-
- /* pcg_dat にパターンデータを読み込む */
- fp = fopen ("ESHOT.SP", "rb");
- fread (pcg_dat, sizeof (char), PCG_MAX * 128, fp);
- fclose (fp);
-
- /* pal_buf に一旦パレットデータを読み込む */
- fp = fopen ("ESHOT.PAL", "rb");
- fread (pal_dat, sizeof (unsigned short), 16 * 15, fp);
- fclose (fp);
- /* パレットデータを定義 */
- /* (1パレットブロック=16色) × (15ブロックぶん) 定義する */
- {
- unsigned short *p = (unsigned short *) pal_dat;
- for (i = 1; i < 15; i++)
- for (j = 0; j < 16; j++)
- _iocs_spalet (0x80000000 | j, i, *p++);
- }
-
- xsp_on ();
- xsp_mode (3);
- /* パターンデータを定義 */
- xsp_pcgdat_set (pcg_dat, pcg_alt, sizeof (pcg_alt));
-
- /* グラフィック画面に線を引く */
- {
- struct _lineptr lp;
- lp.x1 = 0;
- lp.y1 = 128;
- lp.x2 = 255;
- lp.y2 = 128;
- lp.color = 15;
- lp.linestyle = 0xaaaa;
- _iocs_line (&lp);
- lp.x1 = 128;
- lp.y1 = 0;
- lp.x2 = 128;
- lp.y2 = 255;
- _iocs_line (&lp);
- }
-
- printf ("ジョイスティックの\n"
- " [B] ボタンを押すと弾を撃ちます\n"
- " [A] ボタンを押すと終了します\n");
-
-
- EshotInit ();
-
- do {
- xsp_vsync (0); /* 垂直同期待ち */
- j = _iocs_joyget (0); /* ジョイスティック0番 */
-
- /* [A] ボタンが押されたか? */
- if ((j & 0b00100000) == 0)
- game_over = !0; /* ゲームオーバーに */
-
- /* [B] ボタンが押されたか? */
- if ((j & 0b1000000) == 0) {
- EshotAlloc (type, 144, 144, angle); /* 種類 type の敵弾を座標(144,144)、角度 angle で発生 */
- angle += 8; /* 角度を進める */
- type++; /* 種類を進める(意味無し) */
- if (type > 5)
- type = 1;
- }
- EshotMove ();
- sprites = xsp_out (); /* 表示 */
-
- printf ("弾数 = %3d \n\x0b", sprites);
- /* 0x0b はカーソルを1行上に移動する */
- /* Human68K ユーザーズマニュアルの付録 ASCII 制御コードの欄参照 */
- } while (!game_over);
-
- xsp_off ();
-
- _iocs_crtmod (16);
- return (0);
- }
-